<?php
/**
 * This is Lil helper. 
 *
 * @copyright     Copyright 2008-2010, LilCake.net
 * @link          http://lilcake.net LilCake.net
 * @package       lil
 * @subpackage    lil.views.helpers
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
/**
 * LilHelper class
 *
 * @uses          Helper
 * @package       lil
 * @subpackage    lil.views.helpers
 */
class LilHelper extends AppHelper {
/**
 * helpers property
 *
 * @var array
 * @access public
 */
	var $helpers = array('Html', 'Paginator');
/**
 * __call method
 *
 * @param mixed $method
 * @param mixed $params
 * @access private
 * @return void
 */
	function __call($method, $params) {
		if (!empty($params[0]) && App::import('Model', $params[0])) {
			$model_name = $params[0];
			if (strpos($model_name, '.') !== false) {
				$model_name = substr($model_name, strpos($model_name, '.') + 1);
			}
			
			$model = new $model_name;
			
			if (is_callable(array($model, $method))) {
				unset($params[0]);
				return (call_user_func_array(array($model, $method), $params));
			}
		}
		return false;
	}
/**
 * user method
 *
 * Returns current user
 *
 * @param mixed $key
 * @access public
 * @return mixed
 */
	function user($key = null) {
		$this->Session = new CakeSession();
		
		if ($this->Session->valid(Configure::read('Lil.authSessionKey'))) {
			if ($key == null) {
				return array(Configure::read('Lil.authModel') => $this->Session->read(Configure::read('Lil.authSessionKey')));
			} else {
				$user = $this->Session->read(Configure::read('Lil.authSessionKey'));
				if (isset($user[$key])) return $user[$key];
			}
		}
		return null;
	}
/**
 * isAdmin method
 *
 * Returns if currently logged user is an administrator
 *
 * @param mixed $key
 * @access public
 * @return mixed
 */
	function isAdmin() {
		$this->Session = new CakeSession();
		
		if ($this->Session->valid(Configure::read('Lil.authSessionKey')) &&
			$user = $this->Session->read(Configure::read('Lil.authSessionKey')))
		{
			return (bool)$user[Configure::read('Lil.userAdminField')];
		}
		return false;
	}
/**
 *  link method
 * 
 * Creates a HTML link. Behaves exactly like Html::link with ability to use 
 * nicer links in form like "[Link] additional data"
 *
 * @param string $title The content to be wrapped by <a> tags.
 * @param mixed $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
 * @param array $options Array of HTML attributes.
 * @param string $confirmMessage JavaScript confirmation message.
 * @return string An <a /> element.
 * @access public
 */
	function link($title, $url = null, $options = array(), $confirmMessage = false) {
		if (preg_match('/\[(.*)\]/', $title, $matches)) {
			$link_element = $this->Html->link($matches[1], $url, $options, $confirmMessage);
			return str_replace($matches[0], $link_element, $title);
		} else {
			return $this->Html->link($title, $url, $options, $confirmMessage);
		}
	}
/**
 * deleteLink method
 *
 * Returns default delete link
 *
 * @param mixed $url_options Either an array with url or model's id
 * @access public
 * @return mixed
 */
	function deleteLink($url_options = array(), $link_options = array(), $image_options = array()) {
		$url_defaults = array(
			'action' => 'delete'
		);
		
		return $this->Html->link(
			$this->Html->image('/lil/img/delete.gif', $image_options),
			array_merge($url_defaults, (array)$url_options),
			array_merge(
				array(
					'escape' => false,
					'confirm' => __d('lil', 'Are you sure you want to delete this record?', true)
				),
				$link_options
			)
		);
	}
/**
 * editLink method
 *
 * Returns default edit link
 *
 * @param mixed $url_options Either an array with url or model's id
 * @param mixed $link_options Array with options applied to link element
 * @param mixed $image_options Array with options applied to image element
 * @access public
 * @return mixed
 */
	function editLink($url_options = array(), $link_options = array(), $image_options = array()) {
		$url_defaults = array(
			'action' => 'edit'
		);
		
		return $this->Html->link(
			$this->Html->image('/lil/img/edit.gif', $image_options),
			array_merge($url_defaults, (array)$url_options),
			array_merge(
				array(
					'escape' => false,
				),
				$link_options
			)
		);
	}
/**
 * viewLink method
 *
 * Returns default view link
 *
 * @param mixed $url_options Either an array with url or model's id
 * @param mixed $link_options Array with options applied to link element
 * @param mixed $image_options Array with options applied to image element
 * @access public
 * @return mixed
 */
	function viewLink($url_options = array(), $link_options = array(), $image_options = array()) {
		$url_defaults = array(
			'action' => 'view'
		);
		
		return $this->Html->link(
			$this->Html->image('/lil/img/view.gif', $image_options),
			array_merge($url_defaults, (array)$url_options),
			array_merge(
				array(
					'escape' => false,
				),
				$link_options
			)
		);
	}
/**
 * paginator method
 *
 * Returns default paginator
 *
 * @param array $pagination_url
 * @access public
 * @return mixed
 */
	function paginator($pagination_url = array()) {
		return
			$this->Paginator->prev(
				'<< ' . __d('lil', 'previous', true),
				array('class' => 'prev', 'url' => $pagination_url),
				null,
				array('class'=>'prev light')
			) .
			$this->Paginator->next(
				__d('lil', 'next', true) . ' >>',
				array('class' => 'next', 'url' => $pagination_url),
				null,
				array('class'=>'next light')
			) .
			'<div class="counter">' . 
			$this->Paginator->counter(
				array('format' => __d('lil', 'Page <b>%page%</b> of <b>%pages%</b>, total <b>%count%</b> records.', true))
			) .
			'</div>';
	}
/**
 * loader method
 *
 * Returns default loader
 *
 * @param mixed $options An array with options for image
 * @access public
 * @return mixed
 */
	function loader($options = array()) {
		return '<span class="lil-loader">' . $this->Html->image('/lil/img/loader.gif', $options) . '</span>';
	}
/**
 * Replaces double line-breaks with paragraph elements.
 *
 * A group of regex replaces used to identify text formatted with newlines and
 * replace double line-breaks with HTML paragraph tags. The remaining
 * line-breaks after conversion become <<br />> tags, unless $br is set to '0'
 * or 'false'.
 *
 * @since 0.71
 *
 * @param string $pee The text which has to be formatted.
 * @param int|bool $br Optional. If set, this will convert all remaining line-breaks after paragraphing. Default true.
 * @return string Text which has been converted into correct paragraph tags.
 */
	function autop($pee, $br = 1) {
		if ( trim($pee) === '' )
			return '';
		$pee = $pee . "\n"; // just to make things a little easier, pad the end
		$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
		// Space things out a little
		$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
		$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
		$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
		$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
		if ( strpos($pee, '<object') !== false ) {
			$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
			$pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
		}
		$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
		// make paragraphs, including one at the end
		$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
		$pee = '';
		foreach ( $pees as $tinkle )
			$pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
		$pee = preg_replace('|<p>\s*</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
		$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
		$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
		$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
		$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
		$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
		$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
		$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
		if ($br) {
			$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<PreserveNewline />", $matches[0]);'), $pee);
			$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
			$pee = str_replace('<PreserveNewline />', "\n", $pee);
		}
		$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
		$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
		if (strpos($pee, '<pre') !== false)
			$pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'clean_pre', $pee );
		$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
		//$pee = preg_replace('/<p>\s*?(' . get_shortcode_regex() . ')\s*<\/p>/s', '$1', $pee); // don't auto-p wrap shortcodes that stand alone

		return $pee;
	}
}

function clean_pre($matches) {
	if ( is_array($matches) )
		$text = $matches[1] . $matches[2] . "</pre>";
	else
		$text = $matches;

	$text = str_replace('<br />', '', $text);
	$text = str_replace('<p>', "\n", $text);
	$text = str_replace('</p>', '', $text);

	return $text;
}